home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
program
/
relmod.arc
/
relmod.asm
< prev
Wrap
Assembly Source File
|
1987-08-24
|
12KB
|
409 lines
*
* New version of relmod.
* Made by J.A.M.Vermaseren, 17-12-1986.
* Public domain. This program may be copied for free only.
* Anybody selling public domain disks with whatever tiny profit
* beyond the direct costs should send me Dfl 2,-- per copy ( $1 ).
* My address : J.Vermaseren, Leerdamhof 441, 1108CL Amsterdam.
* Be fair : If you get something for the trouble I want something
* for mine.
*
******************************************************************************
* *
* Variables in the heap : ( a6 is heap pointer ) *
* *
* 0 Number of characters read into input buffer *
* 4 Output error information from reloc. *
* 8 Last relocation address. *
* 12 Little trap routine. *
* 24 Input name. *
* *
* Variables in the registers : *
* *
* d7 Input file handle *
* d6 Output file handle *
* d5 (reloc) characters in output buffer *
* d4 (reloc) characters in input buffer *
* d3 Length of the buffers *
* d2 (reloc) Distance to start of text *
* a5 Output buffer *
* a4 (reloc) Input buffer *
* a3 (reloc) Next position in output buffer *
* a2 (reloc) Next position in input buffer *
* *
******************************************************************************
*
* The startup is done in a particular way, to build the heap before
* the setblock is done. The Atari ROM refuses to execute trap functions
* and return to the ROM safely. This way a little routine like
* move.l (sp)+,offset+8(a6)
* trap #1
* jmp unimportant
* can be put at offset(a6) and all trap #1 replaced by jmp offset(a6).
* In this program offset is 12, so jmp 12(a6) is equivalent to trap #1
* This has to be done before the first trap call, ie the setblock.
*
start: move.l 4(sp),a3 * Base page address.
move.l 12(a3),d0 * Length of text.
add.l 20(a3),d0 * Initialized data.
add.l 28(a3),d0 * Uninitialized data.
add.l #$100,d0 * + 100 bytes basepage.
lea (a3,d0.l),a6 * Heap pointer.
add.l #$200,d0 * Heap + stack space.
move.l sp,d3 * Top of available memory.
lea (a3,d0.l),sp * Install new stack pointer
sub.l sp,d3 * Available for copying.
andi.l #$FFFFF800,d3 * Make multiple of 2048.
beq nomemory * Not enough memory.
add.l d3,d0 * Total memory requirement.
lsr.l #1,d3 * Space for each buffer.
move.l sp,-(sp) * Input buffer for later.
lea (sp,d3.l),a5 * Output buffer.
*
* Just for fun. I don't expect you to put it in the ROM cartridge.
*
move.l #$2D5F0014,12(a6) * move.l (sp)+,20(a6)
move.l #$4E414EF9,16(a6) * trap #1
* * jmp .....
*
move.l d0,-(sp) * Total reservation.
move.l a3,-(sp) * Start address.
clr.w -(sp) * For GEMDOS. It eats its stack!!!!!!
move.w #$4A,-(sp) * Setblock.
jsr 12(a6) * This is trap #1
lea 12(sp),sp * Reset the stack.
tst.l d0
bne nomemory
*
* Study the command tail. Problem : What if there ain't any.
* Normally : Pascal string : One byte with the length of the rest, and
* then the rest.
* Is none : 60,1A or something. So if 60, then look at offset 18. If
* no tail there is a zero there. With tail there ain't.
*
lea $80(a3),a4 * The beginning of the command tail
moveq.l #0,d5
move.b (a4)+,d5 * String length. String at a4.
beq notail * Length 0.
cmpi.w #$60,d5
bne istail * There is a command tail.
tst.b 17(a4)
beq notail * No commmand tail --> error message.
istail: lea (a4,d5.w),a3 * First address beyond the tail.
moveq.l #0,d0
moveq.l #$20,d2 * This is a blank.
loop1: move.b (a4)+,d0 * Get one character.
cmp.b d2,d0
beq loop1 * Strip leading blanks.
cmpi.b #$2D,d0
bne nodash
move.b (a4)+,d0 * Skip a dash.
nodash: cmp.l a4,a3 * Do we have a nontrivial character ?
blt notail
lea 24(a6),a0 * For storage.
move.l a0,a1 * For later to find the extention.
move.l a0,a2 * Keep track of the '.'
loop2: cmp.b #$2E,d0
bne loop2a
move.l a0,a2 * Address of the last period
loop2a: move.b d0,(a0)+
move.b (a4)+,d0
cmp.b d2,d0 * Go till blank or end of tail
beq endpar
cmp.l a4,a3
bge loop2 * A good character --> copy.
endpar:
cmp.l a2,a1 * Was there a period ?
bne fullnm * Got a full name.
move.l a0,a2
move.b #$2E,(a0)+ * '.'
move.b #$36,(a0)+ * '6'
move.b #$38,(a0)+ * '8'
move.b #$4B,(a0)+ * 'K'
fullnm: clr.b (a0)
clr.w -(sp) * Reading this file only.
move.l a1,-(sp) * Address of the file name.
move.w #$3D,-(sp) * Fopen.
jsr 12(a6) * This is trap #1
addq.l #8,sp
tst.l d0 * Did the file get opened?
bmi filerr
move.l d0,d7 * Store the handle.
*
moveq.l #0,d0
loop3: move.b (a4)+,d0
cmp.b d2,d0
beq loop3
cmp.l a4,a3
bmi only1 * Only one parameter --> transform.
lea -1(a4),a1 * Start of second name.
loop4: move.b (a4)+,d0
cmp.b d2,d0
beq param2
cmp.l a4,a3
bge loop4
bra param2
only1: lea 1(a2),a4
move.b #$50,(a4)+
move.b #$52,(a4)+
move.b #$47,(a4)+
addq.l #1,a4
param2: subq.l #1,a4
move.b (a4),d4 * Save old character
clr.b (a4) * End on 0 for GEMDOS.
clr.w -(sp) * Read and write.
move.l a1,-(sp)
move.w #$3C,-(sp) * Fcreate
jsr 12(a6) * This is trap #1
addq.l #8,sp
move.b d4,(a4) * Restore old character.
tst.l d0
bmi filer2
move.l d0,d6 * Save the output handle.
*
* Now we have two opened files and the buffers are ready.
*
move.l (sp)+,a4 * Input buffer.
bsr reloc * Make the relocation table.
move.w d6,-(sp) * Output file.
bsr fclose
move.w d7,(sp) * Input file.
bsr fclose
addq.l #2,sp
move.w 4(a6),-(sp) * Error code from reloc ( or none ).
move.w #$4C,-(sp) * Pterm: exit with possible error code.
jsr 12(a6) * This is trap #1
*
* Error messages when a file cannot be opened.
*
filer2: move.w d7,-(sp)
bsr fclose * First close the input file.
addq.l #2,sp
*
filerr: pea nofil(pc) * First part of error message.
bsr out_str
addq.l #4,sp
move.l a1,-(sp) * Pointer to the name of the file.
conti: bsr out_str
addq.l #4,sp
pea newlin(pc) * CR+linefeed.
bsr out_str
addq.l #4,sp
bra errext
*
nomemory:
pea nomem(pc) * Shortage of memory.
bra conti
*
notail: pea use(pc) * Show correct usage.
bsr out_str
addq.l #4,sp
errext:
move.w #-1,-(sp)
move.w #$4C,-(sp)
jsr 12(a6) * Pterm with errorflag.
*
use: dc.b 'Usage: FASTREL [-]file[.68K] [output file]'
newlin: dc.b $0D,$0A,0,0
nofil: dc.b 'Cannot open file ',0
nomem: dc.b 'Not enough memory available.',0,0
errrel: dc.b 'File error.',0
*
* Close a file
*
fclose: move.w 4(sp),-(sp)
move.w #$3E,-(sp) * Fclose
jsr 12(a6) * This is trap #1
addq.l #4,sp
rts
*
* Routine to write a zero terminated string to the screen.
*
out_str:
move.l 4(sp),-(sp)
move.w #9,-(sp)
jsr 12(a6) * This is trap #1
addq.l #6,sp
rts
*
* The routine to make a relocation table.
*
reloc: bsr readin * Read the first buffer.
bmi error
moveq.l #28,d4 * Header length.
add.l 2(a4),d4 * Text length.
add.l 6(a4),d4 * Data segment.
add.l 14(a4),d4 * Symbol table.
bsr copyd4 * Copy this piece to the output buffer.
bmi error
clr.l 8(a6) * Start of relocation
moveq.l #-4,d2 * Running counter.
rloop: addq.l #2,d2
rloopp: addq.l #2,d2
bsr getone * Get a single relocation number in d1.
bne relend
andi.w #7,d1
cmpi.w #5,d1
bne rloopp * Not relevant on the ST.
bsr getone * Upper half of a long word. Get next.
bne relend * Originally:
subq.w #1,d1 * 1 relative to data segment
andi.w #7,d1 * 2 relative to text segment
cmp.w #3,d1 * 3 relative to bss
bge rloop * On the ST its all relative to text.
relo1: tst.l 8(a6) * First relocation?
bne relo2 * No
move.l d2,8(a6)
move.l d2,d1
rol.l #8,d1 * Put now the 4 bytes of d1.
bsr putone
bne error
rol.l #8,d1
bsr putone
bne error
rol.l #8,d1
bsr putone
bne error
rol.l #8,d1
bsr putone
beq rloop
bra error
relo2: move.l d2,d1
sub.l 8(a6),d1 * Difference with the previous one.
move.l d2,8(a6) * The new 'previous one'
bra relo4
relo3: move.l d1,d2 * If > 254 --> write a 1
sub.l #254,d2 * and subtract 254.
moveq.l #1,d1
bsr putone
bne error
move.l d2,d1
move.l 8(a6),d2 * We needed register d2 for scratch.
relo